package com.huantai.common.util.file;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import com.huantai.common.exception.SystemException;

/**
 * 根据URL获取文件的工具类
 * 
 * @author Ma Chao
 * @version 2019年5月28日 下午3:00:33
 */
public final class UrlFileUtil {
    private UrlFileUtil() {}

    /**
     * 加载网络文件内容
     */
    public static byte[] loadFileByteFromURL(String fileUrl) {
        if (fileUrl.startsWith("http://")) {
            return httpConverBytes(fileUrl);
        } else if (fileUrl.startsWith("https://")) {
            return httpsConverBytes(fileUrl);
        }
        return new byte[] {};
    }

    private static byte[] httpConverBytes(String fileUrl) {
        try (ByteArrayOutputStream out = new ByteArrayOutputStream(1024)) {
            URL url = new URL(fileUrl);
            URLConnection conn = url.openConnection();
            BufferedInputStream in = new BufferedInputStream(conn.getInputStream());
            byte[] temp = new byte[1024];
            int size = 0;
            while ((size = in.read(temp)) != -1) {
                out.write(temp, 0, size);
            }
            return out.toByteArray();
        } catch (Exception e) {
            throw new SystemException("");
        }
    }

    private static byte[] httpsConverBytes(String fileUrl) {
        try (ByteArrayOutputStream outStream = new ByteArrayOutputStream()) {

            TrustManager[] tm = {new TrustAnyTrustManager()};
            SSLContext sc = SSLContext.getInstance("SSL", "SunJSSE"); // NOSONAR
            sc.init(null, tm, new java.security.SecureRandom());
            URL console = new URL(fileUrl);

            HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
            conn.setSSLSocketFactory(sc.getSocketFactory());
            conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setRequestMethod("GET");
            conn.connect();

            BufferedInputStream inStream = new BufferedInputStream(conn.getInputStream());

            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outStream.write(buffer, 0, len);
            }
            return outStream.toByteArray();
        } catch (Exception e) {
            throw new SystemException("");
        }
    }

    /**
     * 信任证书的管理器
     */
    private static class TrustAnyTrustManager implements X509TrustManager {
        public void checkClientTrusted(X509Certificate[] chain, String authType) // NOSONAR
                throws CertificateException {}

        public void checkServerTrusted(X509Certificate[] chain, String authType) // NOSONAR
                throws CertificateException {}

        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[] {};
        }
    }

    /**
     * 信任HOST的验证器
     */
    private static class TrustAnyHostnameVerifier implements HostnameVerifier {
        public boolean verify(String hostname, SSLSession session) {
            return true; // NOSONAR
        }
    }
}
